import {InstanceType} from "typegoose";
import {GameActivityModel} from "../../database/models/gameActivity";
import {LipstickSeries, PlayerSeriesIncome, PlayerSeriesIncomeModel} from "../../database/models/lipstickSeries";
import {Player} from "../../database/models/player";
import {
  Product,
  RMB_2_COIN_RATE,
} from "../../database/models/Product";
import {SeriesIncomeThreshold, SeriesIncomeThresholdModel} from "../../database/models/seriesIncomeThreshold";
import {expect, requestToApiServer, setupTestEnv, tearDownTestEnv, TestEnv} from "./helper";

describe('玩家幸运值', () => {

  let player: InstanceType<Player> = null
  let gift: InstanceType<Product> = null
  let jwt: string = null
  let lipstickSeries: InstanceType<LipstickSeries> = null
  let env: TestEnv = null

  before(async () => {
    env = await setupTestEnv()

    player = env.player
    gift = env.gift
    jwt = env.jwt
    lipstickSeries = env.lipstickSeries
  })

  after(async () => {
    return await tearDownTestEnv()
  })

  beforeEach(async () => {
    return await PlayerSeriesIncomeModel.deleteMany({})
  })

  afterEach(async () => {
    return await GameActivityModel.deleteMany({})
  })

  it('查询玩家某口红机系列幸运值', async function () {

    let currentActivityData = null
    await requestToApiServer()
      .post(`/game/start/${lipstickSeries._id}`)
      .set({'x-jwt': jwt})
      .then(res => {
        expect(res.body).to.have.properties({ok: true})
        currentActivityData = res.body.data
      })

    await requestToApiServer()
      .post(`/game/claim/${currentActivityData.activity}`)
      .set({'x-jwt': jwt})
      .send({win: false, stage: 0})
      .expect(200)
      .then(res => {
        expect(res.body).to.have.properties({
          ok: true, data: {
            win: false
          }
        })
      })

    await requestToApiServer()
      .get(`/player/income/${lipstickSeries._id}`)
      .set({'x-jwt': jwt})
      .expect(200)
      .then(async res => {
        const psi: InstanceType<PlayerSeriesIncome> = await PlayerSeriesIncomeModel.findOne({
          player: player._id,
          lipstickSeries: lipstickSeries.id
        })
        const sit: InstanceType<SeriesIncomeThreshold> = await SeriesIncomeThresholdModel.findOne({
          lipstickSeries: lipstickSeries._id
        })

        expect(res.body).to.have.properties({
          ok: true, data: {
            canUse: false,
            percentage: psi.income / (lipstickSeries.seriesPrice * RMB_2_COIN_RATE * sit.thresholdCoinRate)
          }
        })
      })
  });

  it('查询玩家所有系列幸运值', async function () {

    let currentActivityData = null
    await requestToApiServer()
      .post(`/game/start/${lipstickSeries._id}`)
      .set({'x-jwt': jwt})
      .then(res => {
        expect(res.body).to.have.properties({ok: true})
        currentActivityData = res.body.data
      })

    await requestToApiServer()
      .post(`/game/claim/${currentActivityData.activity}`)
      .set({'x-jwt': jwt})
      .send({win: false, stage: 0})
      .expect(200)
      .then(res => {
        expect(res.body).to.have.properties({
          ok: true, data: {
            win: false
          }
        })
      })

    await requestToApiServer()
      .post(`/game/start/${lipstickSeries._id}`)
      .set({'x-jwt': jwt})
      .then(res => {
        expect(res.body).to.have.properties({ok: true})
        currentActivityData = res.body.data
      })

    await requestToApiServer()
      .post(`/game/claim/${currentActivityData.activity}`)
      .set({'x-jwt': jwt})
      .send({win: false, stage: 0})
      .expect(200)
      .then(res => {
        expect(res.body).to.have.properties({
          ok: true, data: {
            win: false
          }
        })
      })

    return await requestToApiServer()
      .get('/lipstickSeries')
      .set({'x-jwt': jwt})
      .then(({body}) => {
        expect(body).to.have.properties({
          ok: true, data: {}
        })
      })
  });

  context('一直输', async () => {
    it('幸运值不够，生成奖品失败', async function () {

      let currentActivityData = null
      await requestToApiServer()
        .post(`/game/start/${lipstickSeries._id}`)
        .set({'x-jwt': jwt})
        .then(res => {
          expect(res.body).to.have.properties({ok: true})
          currentActivityData = res.body.data
        })

      await requestToApiServer()
        .post(`/game/claim/${currentActivityData.activity}`)
        .set({'x-jwt': jwt})
        .send({win: false, stage: 0})
        .expect(200)
        .then(res => {
          expect(res.body).to.have.properties({
            ok: true, data: {
              win: false
            }
          })
        })

      await requestToApiServer()
        .post(`/player/income/prize/${lipstickSeries.id}`)
        .set({'x-jwt': jwt})
        .expect(200)
        .then(res => {
          expect(res.body).to.have.properties({
            ok: false
          })
        })
    });

    it('幸运值够了，请求扣除幸运值且生成奖品', async function () {

      let currentActivityData = null
      await requestToApiServer()
        .post(`/game/start/${lipstickSeries._id}`)
        .set({'x-jwt': jwt})
        .then(res => {
          expect(res.body).to.have.properties({ok: true})
          currentActivityData = res.body.data
        })

      await requestToApiServer()
        .post(`/game/claim/${currentActivityData.activity}`)
        .set({'x-jwt': jwt})
        .send({win: false, stage: 0})
        .expect(200)
        .then(res => {
          expect(res.body).to.have.properties({
            ok: true, data: {
              win: false
            }
          })
        })

      await PlayerSeriesIncomeModel.updateOne({
        player: player.id,
        lipstickSeries: lipstickSeries._id
      }, {income: 10000})

      await requestToApiServer()
        .post(`/player/income/prize/${lipstickSeries._id}`)
        .set({'x-jwt': jwt})
        .expect(200)
        .then(res => {
          expect(res.body).to.have.properties({
            ok: true
          })
        })

      const psi = await PlayerSeriesIncomeModel.findOne({
        player: player.id,
        lipstickSeries: lipstickSeries._id
      })

      expect(psi.income).to.equal(0)

    })
  })

  context('输了一段时间，赢了一把', async () => {

    it('重置幸运值', async () => {
      const {body} = await requestToApiServer()
        .post(`/game/start/${lipstickSeries.id}`)
        .set({'x-jwt': jwt})
        .expect(200)
        .send()

      const act = body.data.activity

      await GameActivityModel.updateOne({_id: act}, {$set: {canWin: true}})

      await requestToApiServer()
        .post(`/game/claim/${act}`)
        .set({'x-jwt': jwt})
        .expect(200)
        .send({win: true, stage: 2})
        .then(({body}) => {
          expect(body).to.have.properties({data: {win: true}})
        })

      await requestToApiServer()
        .post('/player/address')
        .set({'x-jwt': jwt})
        .send({
          pcas: '330108003',
          address: '保亿大厦2222室',
          receiver: 'pshu',
          phone: '18688887777',
          alias: '公司2',
          default: true
        })
        .expect(200)
        .then(({body}) => {
        })

      const psi = await PlayerSeriesIncomeModel.findOne({
        player: player.id,
        lipstickSeries: lipstickSeries.id
      })
      expect(psi.income).to.equal(0)
    })
  })
})
